﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ChoWorkflowServer.Model;
using System.ServiceModel;
using Cinchoo.Core.Xml.Serialization;
using System.IO;
using Cinchoo.IO;

namespace ChoWorkflowServer.ModelWCF
{
    public class ChoDataModel : IChoDataModel
    {
        private readonly ChoWorkflowServerSettings _workflowServerSettings = new ChoWorkflowServerSettings();
        private readonly IChoDataModel _channel;

        public ChoDataModel()
        {
            BasicHttpBinding binding = new BasicHttpBinding();
            binding.Name = "binding1";
            //binding.UseDefaultWebProxy = false;
            binding.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard;
            binding.MaxReceivedMessageSize = 2147483647;

            //binding.Security.Mode = SecurityMode.Message;
            //binding.ReliableSession.Enabled = false;
            //binding.TransactionFlow = false;

            String url = _workflowServerSettings.DataModelHostUrl;
            if (!url.IsNullOrWhiteSpace())
            {
                Uri uri = new Uri(url, UriKind.Absolute);
                EndpointAddress address = new EndpointAddress(uri);
                ChannelFactory<IChoDataModel> channelFactory = new ChannelFactory<IChoDataModel>(binding, address);
                _channel = channelFactory.CreateChannel();
                IClientChannel contextChannel = _channel as IClientChannel;
                contextChannel.OperationTimeout = TimeSpan.FromSeconds(_workflowServerSettings.OperationTimeout);
            }
            else
                _channel = new ChoNullDataModel();
        }

        public void Dispose()
        {
        }

        public int GetTaskId(string taskName)
        {
            return _channel.GetTaskId(taskName);
        }

        public bool IsTaskExists(string taskName)
        {
            return _channel.IsTaskExists(taskName);
        }
        
        public int AddOrUpdateTask(string taskName, string workflowName, string taskDesc, int taskGroupId, string cmdParameters,
            int? maxNoOfRetry, int? sleepBetweenRetry, int? timeout, string hostName,
            ChoTasksDataSet.CHO_TASK_SCHEDULESDataTable taskScheduleInfo, string modifiedBy, string machineName)
        {
            return _channel.AddOrUpdateTask(taskName, workflowName, taskDesc, taskGroupId, cmdParameters,
                maxNoOfRetry, sleepBetweenRetry, timeout, hostName, taskScheduleInfo, modifiedBy, machineName);
        }

        public int CloneTask(string taskName, string newTaskName, string taskGroupName, string newTaskGroupName, string modifiedBy, string machineName)
        {
            return _channel.CloneTask(taskName, newTaskName, taskGroupName, newTaskGroupName, modifiedBy, machineName);
        }

        public void DeleteTask(string taskName, string modifiedBy, string machineName)
        {
            _channel.DeleteTask(taskName, modifiedBy, machineName);
        }

        public ChoTasksDataSet.CHO_TASKSDataTable GetAllUITasks(string taskName, string taskGrpName)
        {
            return _channel.GetAllUITasks(taskName, taskGrpName);
        }
        
        public ChoTasksDataSet.CHO_TASKSDataTable GetAllTasks(string taskName, string taskGrpName, string machineName, DateTime modifiedDate)
        {
            return _channel.GetAllTasks(taskName, taskGrpName, machineName, modifiedDate);
        }

        public void SetTaskStatus(int batchId, string taskName, string scheduleName, Cinchoo.Core.ETL.ChoETLWorkflowStatus taskStatus, string modifiedBy, string modifiedByHostName, string logMsg = null, string nextRunTime = null, string machineName = null)
        {
            _channel.SetTaskStatus(batchId, taskName, scheduleName, taskStatus, modifiedBy, modifiedByHostName, logMsg, nextRunTime, machineName);
        }

        public int AddOrUpdateTaskGroup(string taskGroupName, string taskGroupDesc, int parent, string modifiedBy, string machineName)
        {
            return _channel.AddOrUpdateTaskGroup(taskGroupName, taskGroupDesc, parent, modifiedBy, machineName);
        }

        public void DeleteTaskGroup(string taskGroupName, string modifiedBy, string machineName)
        {
            _channel.DeleteTaskGroup(taskGroupName, modifiedBy, machineName);
        }
        
        public bool IsTaskGroupExists(string taskGroupName)
        {
            return _channel.IsTaskGroupExists(taskGroupName);
        }

        public void ImportTasks(ChoTasksDataSet dsTasks, string modifiedBy, string machineName)
        {
            _channel.ImportTasks(dsTasks, modifiedBy, machineName);
        }

        public ChoTasksDataSet.CHO_HOLIDAY_CALENDARSDataTable GetAllHolidayCalendars()
        {
            return _channel.GetAllHolidayCalendars();
        }
        
        public void UpdateHolidayCalendar(ChoTasksDataSet.CHO_HOLIDAY_CALENDARSDataTable calendarTable,
            ChoTasksDataSet.CHO_HOLIDAY_CALENDAR_DATESDataTable calendarDatesTable, string modifiedBy, string machineName)
        {
            _channel.UpdateHolidayCalendar(calendarTable, calendarDatesTable, modifiedBy, machineName);
        }

        public ChoTasksDataSet.CHO_HOLIDAY_CALENDAR_DATESDataTable GetAllHolidayCalendarDatesById(int holidayCalId)
        {
            return _channel.GetAllHolidayCalendarDatesById(holidayCalId);
        }
        
        public ChoTasksDataSet.CHO_HOLIDAY_CALENDAR_DATESDataTable GetAllHolidayCalendarDatesByName(string holidayCalName)
        {
            return _channel.GetAllHolidayCalendarDatesByName(holidayCalName);
        }

        public ChoTasksDataSet.CHO_TASK_SCHEDULESDataTable GetTaskSchedules(int taskId, string scheduleName)
        {
            return _channel.GetTaskSchedules(taskId, scheduleName);
        }
        
        public ChoTasksDataSet.CHO_SCHEDULE_TYPESDataTable GetTaskScheduleTypes()
        {
            return _channel.GetTaskScheduleTypes();
        }
        
        public void AddOrUpdateTaskBatch(int batchId, string taskName, string scheduleName, int taskStatus, string cmdParameters, string machineName, string logMsg,
            DateTime processStart, DateTime? processEnd, TimeSpan? duration, string nextRunTime, int exitCode, int? retryCount,
            string modifiedBy, string modifiedByHostName)
        {
            _channel.AddOrUpdateTaskBatch(batchId, taskName, scheduleName, taskStatus, cmdParameters, machineName, logMsg,
                processStart, processEnd, duration, nextRunTime, exitCode, retryCount, modifiedBy, modifiedByHostName);
        }
        
        public ChoTasksDataSet.CHO_POLICYDataTable GetAllPolicy()
        {
            return _channel.GetAllPolicy();
        }
        
        public ChoTasksDataSet.CHO_USERSDataTable GetAllUsers()
        {
            return _channel.GetAllUsers();
        }

        public void UpdateUsers(ChoTasksDataSet.CHO_USERSDataTable usersTable, string modifiedBy, string machineName)
        {
            _channel.UpdateUsers(usersTable, modifiedBy, machineName);
        }

        public ChoTasksDataSet.CHO_ROLESDataTable GetAllRoles()
        {
            return _channel.GetAllRoles();
        }
        
        public ChoTasksDataSet.CHO_ROLE_USERSDataTable GetAllUserRoles(int roleId)
        {
            return _channel.GetAllUserRoles(roleId);
        }
        
        public ChoTasksDataSet.CHO_ROLE_POLICYDataTable GetAllRolePolicy(int roleId)
        {
            return _channel.GetAllRolePolicy(roleId);
        }
        
        public void UpdateRoles(ChoTasksDataSet.CHO_ROLESDataTable rolesTable,
            ChoTasksDataSet.CHO_ROLE_USERSDataTable userRolesTable, ChoTasksDataSet.CHO_ROLE_POLICYDataTable rolesPolicyTable, 
            string modifiedBy, string machineName)
        {
            _channel.UpdateRoles(rolesTable, userRolesTable, rolesPolicyTable, modifiedBy, machineName);
        }
        
        public ChoTasksDataSet.CHO_POLICYDataTable GetPolicyForUser(string userName)
        {
            return _channel.GetPolicyForUser(userName);
        }

        public Cinchoo.Core.ETL.ChoETLWorkflowStatus GetTaskStatus(string taskName, string scheduleName)
        {
            return _channel.GetTaskStatus(taskName, scheduleName);
        }

        public ChoTasksDataSet.CHO_DEPENDENCY_TASKSDataTable GetAllDepedencyTasks(string jobName)
        {
            return _channel.GetAllDepedencyTasks(jobName);
        }

        public int GetTaskExitCode(string taskName, string scheduleName)
        {
            return _channel.GetTaskExitCode(taskName, scheduleName);
        }

        public int CloneCalendar(string calName, string newCalName, string modifiedBy, string machineName)
        {
            return _channel.CloneCalendar(calName, newCalName, modifiedBy, machineName);
        }

        public void MoveTask(string taskName, int srcTaskGrpId, int destTaskGrpId, string modifiedBy, string machineName)
        {
            _channel.MoveTask(taskName, srcTaskGrpId, destTaskGrpId, modifiedBy, machineName);
        }

        public Version GetVersion()
        {
            return _channel.GetVersion();
        }

        public KeyValuePair<string, string>[] GetClusterNodePairs()
        {
            return _channel.GetClusterNodePairs();
        }

        public byte[] DownloadWFPlugIn(string wfPlugInFileName)
        {
            return _channel.DownloadWFPlugIn(wfPlugInFileName);
        }

        public ChoFSFileInfo[] GetWFPlugInsFileList()
        {
            return _channel.GetWFPlugInsFileList();
        }

        public byte[] DownloadWFDef(string wfDefFileName)
        {
            return _channel.DownloadWFDef(wfDefFileName);
        }
        public ChoFSFileInfo[] GetWFDefsFileList()
        {
            return _channel.GetWFDefsFileList();
        }

        public byte[] DownloadWFData(string wfDataRelativeFilePath)
        {
            return _channel.DownloadWFData(wfDataRelativeFilePath);
        }

        public ChoFSFileInfo[] GetWFDataFileList()
        {
            return _channel.GetWFDataFileList();
        }

        public void FireDependentTasks(int batchId, string taskName, string scheduleName, string user, string originHostName)
        {
            _channel.FireDependentTasks(batchId, taskName, scheduleName, user, originHostName);
        }

        public ChoTasksDataSet.CHO_TASK_GRPSDataTable GetAllTaskGroups()
        {
            return _channel.GetAllTaskGroups();
        }

        public bool IsUserPolicyEnabled()
        {
            return _channel.IsUserPolicyEnabled();
        }

        public void RefreshDB()
        {
            _channel.RefreshDB();
        }

        public IChoWorkflowScheduler WorkflowScheduler
        {
            get { return null; }
            set { }
        }
    }
}
